/*
 * FNISVGEditor - JavaScript - based editor for SVG graphics 
 * Copyright (C) 2008 - 2009 Antti Leppä / Foyt
 * http://www.foyt.fi
 * 
 * License: 
 * 
 * Licensed under GNU Lesser General Public License Version 2.1 or later (the "LGPL") 
 * http://www.gnu.org/licenses/lgpl.html
 */
FNISVGEditorViewPort = Class.create({
  initialize: function(editorInstance){
    this._editorInstance = editorInstance;
    this._keyDownListener = this._onKeyDown.bindAsEventListener(this);
    Event.observe(window, "keydown", this._keyDownListener);
  },
  deinitialize: function($super){
    Event.stopObserving(window, "keydown", this._keyDownListener);
	$super();
  },
  setPageSize: function (width, height) {
    if (!this._pageRect) {
      var pageConf = this._editorInstance.getConfigurationManager().getValue("page");
      
      this._pageRect = this._editorInstance.getSVGDocument().createElement("rect");
      this._pageRectShadow = this._editorInstance.getSVGDocument().createElement("rect");    
      
      FNISVGEditorElementStylingUtils.setStyles(this._pageRect, pageConf.rectStyle);
      FNISVGEditorElementStylingUtils.setStyles(this._pageRectShadow, pageConf.rectShadowStyle);
      this._pageRectShadow.setAttribute("x", pageConf.shadowDistance);
      this._pageRectShadow.setAttribute("y", pageConf.shadowDistance);
      
      this._editorInstance.getSVGDocument().getBackgroundGroup().appendChild(this._pageRectShadow);
      this._editorInstance.getSVGDocument().getBackgroundGroup().appendChild(this._pageRect);               
    }
    
    this._pageSize = {
      width: width, 
      height: height
    };
    
    this._pageRect.setAttribute("width", width);
    this._pageRect.setAttribute("height", height);
    this._pageRectShadow.setAttribute("width", width + 1);
    this._pageRectShadow.setAttribute("height", height + 1);
  },
  getPageSize: function () {
    return this._pageSize;
  },
  zoomToPage: function () {
    var pageSize = this.getPageSize();
    var viewDims = this._getViewDimensions();
    var width = pageSize.width + 20;
    var height = pageSize.height + 20;
    var x = -10;
    var y = -10;
    
    if ((viewDims.width / pageSize.width) > (viewDims.height / pageSize.height)) {
      width = height * (viewDims.width / viewDims.height);
      x = - (width - pageSize.width) / 2; 
    } else {
      height = width * (viewDims.height / viewDims.width);     
      y = - (height - pageSize.height) / 2;   
    }
    
    this.setViewBox(x, y, width, height);
  },
  getViewBox: function(){
    var viewBox = this._editorInstance.getSVGDocument().getViewBox();
    if (viewBox == null) {
      var dimensions = this._getViewDimensions();
      this.setViewBox(0, 0, dimensions.width, dimensions.height);
    }
    
    return this._editorInstance.getSVGDocument().getViewBox();
  },
  moveViewBox: function(x, y){
    var viewBox = this._editorInstance.getSVGDocument().getViewBox();
    this._editorInstance.getSVGDocument().setViewBox(viewBox.x + (x * this._zoomFactor), viewBox.y + (y * this._zoomFactor), viewBox.width, viewBox.height);
    viewBox = this._editorInstance.getSVGDocument().getViewBox();
    this.fire("viewboxChanged", {
      x1: viewBox.x,
      y1: viewBox.y,
      x2: viewBox.x + viewBox.width,
      y2: viewBox.y + viewBox.height,
      height: viewBox.height,
      width: viewBox.width,
      zoom: this._zoomFactor
    });
  },
  setViewBox: function(x, y, w, h){
    var viewDimensions = this._getViewDimensions();
    var height = h;
    var width = w;
    var aspect = this._getViewAspectRatio();
    height = w * aspect;
    
    width = Math.round(width);
    height = Math.round(height);
    
    var zoomFactor = viewDimensions.width / width;
    if (zoomFactor > 0.1) {
      this._editorInstance.getSVGDocument().setViewBox(x, y, width, height);
      this._zoomFactor = zoomFactor;
      
      this.fire("viewboxChanged", {
        x1: x,
        y1: y,
        x2: x + width,
        y2: y + height,
        height: height,
        width: width,
        zoom: this._zoomFactor
      });
    }
  },
  setCenter: function(x, y){
    var vp = this._editorInstance.getSVGDocument().getViewBox();
    this._editorInstance.getSVGDocument().setViewBox(x - (vp.width / 2), y - (vp.height / 2), vp.width, vp.height);
  },
  centerOnPage: function () {
    var pageSize = this.getPageSize();
    this.setCenter(pageSize.width / 2, pageSize.height / 2);
  },
  getZoomFactor: function(){
    return this._zoomFactor;
  },
  zoomOut: function(){
    var viewBox = this.getViewBox();
    this.setViewBox(viewBox.x, viewBox.y, viewBox.width + 20, viewBox.height + 20);
  },
  zoomIn: function(){
    var viewBox = this.getViewBox();
    var newWidth = viewBox.width - 20;
    var newHeight = viewBox.height - 20;
    
    if ((newWidth > 0) && (newHeight > 0)) 
      this.setViewBox(viewBox.x, viewBox.y, newWidth, newHeight);
  },
  setZoom: function(zoom){
    var viewDimensions = this._getViewDimensions();
    var viewBox = this.getViewBox();
    
    var width = viewDimensions.width / zoom;
    var height = viewDimensions.height / zoom;
    
    this.setViewBox(viewBox.x, viewBox.y, width, height);
  },
  getElementAt: function (x, y) {
    var elements = this.getElements();
    if (elements != null) {
      for (var i = 0; i < elements.length; i++) {
        var element = elements[i];
        var eBBox = fi.foyt.svg.svgdom.FNISVGDOMUtils.getScreenBBox(element);
        if (eBBox != null) {
          if ((eBBox.x <= x) && (eBBox.y <= y) && ((eBBox.x + eBBox.width) >= x) && ((eBBox.y + eBBox.height) >= y)) 
            return element;
        }
      }
    }
    
    return null;
  },
  getElements: function(){
    // TODO: doesnt work right, it should return all visible elements, instead it returns ALL the elements 
    return this._editorInstance.getSVGDocument().getElements();
  },
  _getViewAspectRatio: function(){
    var dimensions = this._getViewDimensions();
    return dimensions.height / dimensions.width;
  },
  _getViewDimensions: function(){
    return this._editorInstance._viewComponent.domNode.getDimensions();
  },
  _onKeyDown: function (event) {
	switch (event.keyCode) {
	  case Event.KEY_RIGHT:		
		var move = this._editorInstance.getSVGDocument().getViewBox().width * FNISVGEditorViewPort.KEY_MOVE_STEP;
  	    this.moveViewBox(move, 0);
      break;
      case Event.KEY_UP:
   	    var move = this._editorInstance.getSVGDocument().getViewBox().height * FNISVGEditorViewPort.KEY_MOVE_STEP;
    	this.moveViewBox(0, -move);
      break;
      case Event.KEY_LEFT:
        var move = this._editorInstance.getSVGDocument().getViewBox().width * FNISVGEditorViewPort.KEY_MOVE_STEP;
        this.moveViewBox(-move, 0);
      break;
      case Event.KEY_DOWN:
     	var move = this._editorInstance.getSVGDocument().getViewBox().height * FNISVGEditorViewPort.KEY_MOVE_STEP;
        this.moveViewBox(0, move);
      break;
    }
  }
});

Object.extend(FNISVGEditorViewPort.prototype, fni.events.FNIEventSupport);

Object.extend(FNISVGEditorViewPort, {
  KEY_MOVE_STEP: 0.01	
});
